/**
 ** doc - Online documentation generator
 *
 * The doc module automatically generates documentation from oj modules.
 *
 */

define('oj/doc',
[
'oj/os',
'oj/file',
'oj/element',
'oj/javascript'
],
function (os, file, element, javascript) {
    'use strict';
    
    var doc = {
        
        /* Functions */
        generate: function(filepath){}
        
    };
    
    
    
    // patterns
    var COMMENTBLOCKS = /\/\*\*[\s\S]*?\*\//gm,
        COMMENTLINE   = /\n\s*\*[^\n]*/gm,
        TRIMLINE      = /\n\s*\*/gm,
        WHITESPACE    = /\s/gm,
        ANCHORREM     = /[ "'\[\]\)?{}]/g,
        ANCHORREP     = /[,\(]/g;
    
    
    
    function libraryIndex(libraryName, libraryPath, container, url, module) {
        os.read(libraryPath, function (result) {
            var table,
                name;
            
            if (oj.isError(result)) {
                return;
            }
            
            element.create(container, 'div', 'moduletitle', [libraryName + ' library']);
            element.create(container, 'table', 'modules', [table = element.create(table, 'tbody')]);
            
            JSON.parse(result).forEach(function (file) {
                if (/\.js$/.test(file)) {
                    name = file.replace(/\.js$/, '');
                    if (name === module) {
                        element.create(table, 'tr', ['<td><b>' + name + '</b></td>']);
                    } else {
                        element.create(table, 'tr', ['<td><a href="' + url + libraryPath + file + '">' + name + '</a></td>']);
                    }
                }
            });
        });
    }
    
    
    doc.generate = function(filepath) {
        /**
         *> doc.generate('filepath')
         * 
         * Renders documentation parsed from the specified filepath
         */
        
        var url = document.location.pathname + '?oj/doc&f=',
            ancestors = os.path.abspath(filepath).split('/'),
            module = ancestors.pop(),
            parent = undefined,
            parentpath,
            siblings = [],
            header = element.create(document.body, 'div', 'header'),
            version = element.create(header, 'span', 'version', ['oj/doc']),
            content = element.create(document.body, 'div', 'content'),
            left = element.create(content, 'div', 'left'),
            main = element.create(content, 'div', 'main');
        
        // Calculate parent/module parts
        if (module === '') {
            module = ancestors.pop();
        }
        
        if (Object.type(module) !== 'Undefined') {
            module = module.replace(/\.js$/, '');
            parent = ancestors.pop();
        }
        
        
        
        
        if (Object.type(parent) === 'Undefined' || parent === '') {
            element.create(header, 'a', {'href': url + filepath}, [module]);
            libraryIndex(module, filepath, main, url, module);
            return;
        }
        
        parentpath = ancestors.join('/') + '/' + parent + '/';
        element.create(header, 'a', {'href': url + parentpath}, [parent]);
        header.innerHTML += ' &gt; ';
        element.create(header, 'a', {'href': url + filepath}, [module]);
        
        libraryIndex(parent, parentpath, left, url, module);
        
        file.open(filepath).read(function (result) {
            if (oj.isError(result)) {
                return;
            }
            
            var description = element.create(main, 'div', 'description'),
                p,
                example,
                anchor,
                fnpath;
            
            result.file.content.match(COMMENTBLOCKS).forEach(function(commentblock) {
                
                commentblock.match(COMMENTLINE).forEach(function (comment) {
                    comment = comment.replace(TRIMLINE, '');
                    
                    if (comment[0] === '*') {
                        element.create(main, 'div', 'moduletitle', [comment.replace(/\*/, '')]);
                        description = element.create(main, 'div', 'moduleintro');
                        p = undefined;
                        example = undefined;
                    
                    } else if (comment[0] === '>') {
                        comment = comment.replace(/>/, '');
                        
                        anchor = comment.replace(ANCHORREM, '');
                        anchor = anchor.replace(ANCHORREP, ',');
                        
                        element.create(main, 'a', 'anchor', {'id': anchor, 'name': anchor, 'href': '#' + anchor}, [
                            element.create('span', 'function', [javascript.highlight(comment)])
                        ]);
                        description = element.create(main, 'div', 'description');
                        p = undefined;
                        example = undefined;
                        
                    } else if (comment.replace(WHITESPACE, '') === '') {
                        p = element.create(description, 'p');
                        example = undefined;
                        
                    } else if (comment[0] === '.') {
                        if (example === undefined) {
                            example = element.create(description, 'pre');
                        }
                        
                        example.innerHTML += javascript.highlight(comment.replace(/\./, '')) + '\n';
                        p = undefined;
                    
                    }  else if (comment[0] === '/') {
                        element.create(description, 'br');
                        
                    } else {
                        example = undefined;
                        if (Object.type(p) === 'Undefined') {
                            p = element.create(description, 'p');
                        }
                        p.innerHTML += comment;
                        
                    }
                });
            });
        });
    };
    
    
    if (oj.main === 'oj/doc') {
        /**
         **oj.main
         *
         * When run as the main application this module will automatically call
         * doc.generate(f), where f is passed as an argument on the URL.
         *
         *. URL:     /?oj/doc&f=/oj/doc.js
         *. oj/term: oj/doc oj/doc.js
         *
         */
        
        oj.args.forEach(function (arg) {
            if (arg[0] === 'f') {
                var filepath = arg[1].replace(/#.*$/, '');
                if (!/\/$/.test(filepath) && !/\.js$/.test(filepath)) {
                    filepath += '.js';
                }
                document.title += ' : ' + os.path.abspath(filepath);
                doc.generate(filepath);
                var anchor = arg[1].replace(/^.*#/, '');
                if (anchor.length > 0) {
                    anchor = document.getElementById(anchor);
                    if (Object.type(anchor) !== 'Null') {
                        anchor.scrollIntoView();
                    }
                }
            }
        });
    }
    
    
    element.create(document.head, 'style', {'type': 'text/css'}, [
        'body {',
        '  font-family: sans-serif;',
        '  margin: 0;',
        '  color: #222222;',
        '  background: #FFFFFF;',
        '}',
        'a {',
        '  color: #F58F31;',
        '}',
        'a:link    {text-decoration: none;}',
        'a:visited {text-decoration: none;}',
        'a:active  {text-decoration: none;}',
        'a:hover   {text-decoration: underline;}',
        '.header {',
        '  background: #333333;',
        '  border-bottom: 1px solid black;',
        '  height: 20px;',
        '  padding: 5px;',
        '  color: #F58F31;',
        '}',
        '.header a {',
        '  color: #FFFFFF;',
        '}',
        '.content {',
        '  display: table;',
        '  width: 100%;',
        '}',
        '.left {',
        '  display: table-cell;',
        '  width: 150px;',
        '  padding: 5px;',
        '  color: #222222;',
        '  border-right: 1px solid #F2F2F2;',
        '}',
        '.main {',
        '  display: table-cell;',
        '  background: #FFFFFF;',
        '  padding-left: 20px;',
        '  padding-right: 20px;',
        '  padding-top: -50px;',
        '  color: #333333;',
        '}',
        '.moduletitle {',
        '  border-bottom: 1px solid #F2F2F2;',
        '  margin-top: 20px;',
        '  margin-left: -20px;',
        '  margin-right: -20px;',
        '  margin-bottom: 20px;',
        '  font-size: 200%;',
        '  padding-top: 10px;',
        '  padding-left: 20px;',
        '  padding-bottom: 10px;',
        '  color: #F58F31;',
        '}',
        '.modules {',
        '  width: 100%;',
        '}',
        '.modules a {',
        '  font-family: monospace;',
        '  font-style: normal;',
        '  color: blue;',
        '}',
        '.description {',
        '  padding-left: 20px;',
        '}',
        'pre {',
        '  background: #333333;',
        '  color: #ffffff;',
        '  border-top: 1px solid #FB5F22;',
        '  border-bottom: 1px solid #FB5F22;',
        '  padding-top: 10px;',
        '  padding-bottom: 10px;',
        '}',
        '.version {',
        '  float: right;',
        '}',
        '.anchor {',
        '  color: #F58F31;',
        '}',
        '.function {',
        '  color: black;',
        '  padding-top: 10px;',
        '  padding-bottom: 10px;',
        '  font-weight: bold;',
        '}'
    ]);
    
    
    
    return doc;
    
});
